﻿using CSRedis;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Impl;
using Quartz.Logging;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;

namespace AdminManagement.QuartzDemo
{
    [ApiExplorerSettings(GroupName = "v1")]
    public class QuartzDemoService : ApplicationService
    {
        private readonly CSRedisClient client;
        private readonly IJobFactory jobFactory;

        public QuartzDemoService(CSRedisClient client, IJobFactory jobFactory)
        {
            this.client = client;
            this.jobFactory = jobFactory;
        }

        public async Task Test()
        {
            //1、创建调度器
            var scheFactory = new StdSchedulerFactory();

            var sche = await scheFactory.GetScheduler();


            //JobDataMap
            IDictionary<string, object> keys = new Dictionary<string, object>();
            keys.Add(nameof(CSRedisClient), client);
            keys.Add(nameof(QuartzDemoService), 1);
            JobDataMap map = new JobDataMap(keys);

            //2、作业---建造者模式
            var jobDetails = 
                JobBuilder.Create<MyJob>()
                .WithIdentity("作业")
                .WithDescription("作业说明")
                .SetJobData(map)
                .Build();


            //3、触发器
            var trigger = TriggerBuilder.Create()
                .WithIdentity("触发器")
                .WithDescription("触发器说明")
                .WithSimpleSchedule(x =>
                {
                    x.WithIntervalInSeconds(1).RepeatForever();
                })
                .StartNow()
                .Build();

            //调度器工厂
            sche.JobFactory = jobFactory;

            //调度
            await sche.ScheduleJob(jobDetails,trigger);

            await sche.Start();
        }
    }

    [PersistJobDataAfterExecution]
    public class MyJob : IJob
    {
        private readonly ILogger<MyJob> logger;

        public MyJob(ILogger<MyJob> logger)
        {
            this.logger = logger;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            IJobDetail jobDetail = context.JobDetail;

            CSRedisClient cSRedisClient = jobDetail.JobDataMap[nameof(CSRedisClient)] as CSRedisClient;

            int i = (int)jobDetail.JobDataMap[nameof(QuartzDemoService)];

            context.JobDetail.JobDataMap.Put(nameof(QuartzDemoService), ++i);

            logger.LogInformation($"当前值：{i}");

            await cSRedisClient.LPushAsync(nameof(MyJob), DateTime.Now);
        }
    }
}
